#pragma once

#ifdef FTLIBCUDA_EXPORTS
#define FTLIBCUDA_API __declspec(dllexport)
#else
#define FTLIBCUDA_API __declspec(dllimport)
#endif

#include "..\FTLib\IFourierTransformStructures.h"
#include "..\FTLib\IPerformanceData.h"

bool FTLIBCUDA_API cuFft_CheckAvailability();

/// <summary>	Get the CuFFT version string. </summary>
///
/// <param name="sz">	  	[out] A pointer to the buffer that receives the string. </param>
/// <param name="pLength">	[in,out] On input, specifies the size of the buffer, in CHARs. On output, the number of CHARs copied to the destination buffer, not including the terminating null character. </param>
///
/// <returns>	True if the buffer was long enough or if it was NULL, false otherwise. </returns>
bool FTLIBCUDA_API cuFft_GetVersionString(char* sz, size_t* pLength);

struct CUDAFTPLANHANDLE
{
private:
	int32_t opaque1;
	intptr_t opaque2;
	intptr_t opaque3;
	intptr_t opaque4;
	float    opaque5;
	uint16_t opaque6;
};

CUDAFTPLANHANDLE FTLIBCUDA_API cuFft_CreatePlan_2dRealToComplexPackedFftw(uint32_t width, uint32_t height, double normalization);
void FTLIBCUDA_API cuFft_2d_RealToComplexPackedFftw(CUDAFTPLANHANDLE plan, const FTLib::FourierTransfRealInputData2d& input, const FTLib::FourierTransfComplexOutput2d& output, FTLib::IPerformanceDataStore* perfData);

CUDAFTPLANHANDLE FTLIBCUDA_API cuFft_CreatePlan_2dRealToComplex(uint32_t width, uint32_t height, double normalization);
void FTLIBCUDA_API cuFft_2d_RealToComplex(CUDAFTPLANHANDLE plan, const FTLib::FourierTransfRealInputData2d& input, const FTLib::FourierTransfComplexOutput2d& output, FTLib::IPerformanceDataStore* perfData);

CUDAFTPLANHANDLE FTLIBCUDA_API cuFft_CreatePlan_2dComplexToComplex(uint32_t width, uint32_t height, double normalization);
void FTLIBCUDA_API cuFft_2d_ComplexToComplex(CUDAFTPLANHANDLE plan, const FTLib::FourierTransfComplexInput2d& input, const FTLib::FourierTransfComplexOutput2d& output, bool forwardDirection, FTLib::IPerformanceDataStore* perfData);

CUDAFTPLANHANDLE FTLIBCUDA_API cuFft_CreatePlan_2dHermetianToReal(uint32_t width, uint32_t height, double normalization);
void FTLIBCUDA_API cuFft_2d_HermetianToReal(CUDAFTPLANHANDLE plan, const FTLib::FourierTransfComplexInput2d& input, const FTLib::FourierTransfRealOutputData2d& output, FTLib::IPerformanceDataStore* perfData);

void FTLIBCUDA_API cuFft_DeletePlan(CUDAFTPLANHANDLE handle);